/* $Id: VBoxMPUtils.cpp $ */
/** @file
 * VBox Miniport utils
 */

 /*
  * Copyright (C) 2011-2020 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
  * available from http://www.virtualbox.org. This file is free software;
  * you can redistribute it and/or modify it under the terms of the GNU
  * General Public License (GPL) as published by the Free Software
  * Foundation, in version 2 as it comes in the "COPYING" file of the
  * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
  * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
  */

#include <ntdef.h>
#include <wdm.h>
#include "common/VBoxMPUtils.h"
#include "trace.h"

#pragma alloc_text(PAGE, VBoxQueryWinVersion)

  /*Returns the windows version we're running on*/
extern "C"
vboxWinVersion_t VBoxQueryWinVersion(UINT32* pbuild)
{
    static ULONG            s_pbuild = 0;
    static vboxWinVersion_t s_WinVersion = WINVERSION_UNKNOWN;

    ULONG major, minor;
    BOOLEAN checkedBuild;

    if (s_WinVersion == WINVERSION_UNKNOWN)
    {
        checkedBuild = PsGetVersion(&major, &minor, &s_pbuild, NULL);
        LOGI("running on version %d.%d, build %d(checked=%d)", major, minor, s_pbuild, (int)checkedBuild);

        if (major > 6)
        {
            /* Everything newer than Windows 8.1, i.e. Windows 10 with major == 10. */
            s_WinVersion = WINVERSION_10;
        }
        else if (major == 6)
        {
            if (minor >= 4)
                s_WinVersion = WINVERSION_10;
            else if (minor == 3)
                s_WinVersion = WINVERSION_81;
            else if (minor == 2)
                s_WinVersion = WINVERSION_8;
            else if (minor == 1)
                s_WinVersion = WINVERSION_7;
            else if (minor == 0)
                s_WinVersion = WINVERSION_VISTA; /* Or Windows Server 2008. */
        }
        else if (major == 5)
        {
            s_WinVersion = (minor >= 1) ? WINVERSION_XP : WINVERSION_2K;
        }
        else if (major == 4)
        {
            s_WinVersion = WINVERSION_NT4;
        }
        else
        {
            LOGW("NT4 required!");
        }
    }

    if (pbuild)
        *pbuild = s_pbuild;

    return s_WinVersion;
}
